#!/usr/bin/env python3

#
# This tool is used to generate the typescript version of mintops.def, used by the WASM jiterpreter.
#

import sys
import os
import re

if len (sys.argv) != 4:
    print ("Usage: genmintops.py <src/mintops.def> <src/interp-simd-intrins.def> <dest/mintops.ts>")
    exit (1)

src_header_path = sys.argv [1]
simd_header_path = sys.argv [2]
output_ts_path = sys.argv [3]

src = open(src_header_path, 'r')
simd_src = open(simd_header_path, 'r')

tab = "    "
header_lines = src.read().splitlines()
# strip preprocessing directives
simd_header_lines = (l for l in simd_src.read().splitlines() if not (l.startswith("#") or l.startswith("//")))
# strip preprocessing directives and add indentation for tslint/eslint
header = "\n".join((tab + l) for l in header_lines if not (l.startswith("#") or l.startswith("//")))
src.close()
simd_src.close()

opdef_regex = r'\s(IR)?OPDEF\((\w+),\s*(.+?),\s*(MintOp\w+)\)'
enum_values = re.sub(
    opdef_regex, lambda m : f"{m.group(2)},", header
)

simd_values_1 = []
simd_values_2 = []
simd_values_3 = []
simd_disp = {
    "INTERP_SIMD_INTRINSIC_P_P": simd_values_1,
    "INTERP_SIMD_INTRINSIC_P_PP": simd_values_2,
    "INTERP_SIMD_INTRINSIC_P_PPP": simd_values_3,
    "INTERP_WASM_SIMD_INTRINSIC_V_P": simd_values_1,
    "INTERP_WASM_SIMD_INTRINSIC_V_V": simd_values_1,
    "INTERP_WASM_SIMD_INTRINSIC_V_C1": simd_values_1,
    "INTERP_WASM_SIMD_INTRINSIC_I_V": simd_values_1,
    "INTERP_WASM_SIMD_INTRINSIC_V_VV": simd_values_2,
    "INTERP_WASM_SIMD_INTRINSIC_V_C2": simd_values_2,
    "INTERP_WASM_SIMD_INTRINSIC_V_VI": simd_values_2,
    "INTERP_WASM_SIMD_INTRINSIC_V_VVV": simd_values_3,
    "INTERP_WASM_SIMD_INTRINSIC_V_C3": simd_values_3,
}

for line in simd_header_lines:
    idx1 = line.index("(") if "(" in line else None
    idx2 = line.index(",") if "," in line else None
    if (idx1 and idx2):
        key = line[0:idx1].strip()
        vals = line[(idx1 + 1):].strip().split(",")
        id = vals[0].replace("INTERP_SIMD_INTRINSIC_", "").strip()
        if (len(vals) == 4):
            id += vals[1].strip()
        simd_disp[key].append(id)

splitter = ",\n    "
splitter2 = ",\n        "

generated = f"""
// Generated by genmintops.py from mintops.def.
// Do not manually edit this file.

import {{ MintOpArgType, SimdInfoTable }} from "./jiterpreter-opcodes";

export const enum MintOpcode {{
{enum_values}

    MINT_LASTOP
}}

export const enum SimdIntrinsic2 {{
    {splitter.join(simd_values_1)}
}}

export const enum SimdIntrinsic3 {{
    {splitter.join(simd_values_2)}
}}

export const enum SimdIntrinsic4 {{
    {splitter.join(simd_values_3)}
}}

export const SimdInfo : SimdInfoTable = {{
    2: [
        {splitter2.join(repr(x) for x in simd_values_1)}
    ],
    3: [
        {splitter2.join(repr(x) for x in simd_values_2)}
    ],
    4: [
        {splitter2.join(repr(x) for x in simd_values_3)}
    ],
}};
"""

os.makedirs(os.path.dirname(output_ts_path), exist_ok=True)
try:
    with open(output_ts_path, 'r') as dest:
        if (dest.read() == generated):
            print("mintops.ts up to date, exiting")
            exit(0)
except FileNotFoundError:
    pass
with open(output_ts_path, 'w') as dest:
    dest.write(generated)
print("mintops.ts generated")
exit(0)
